示例#1
0
    def __init__(self, args):
        self.args = args
        self.tribler_path = args.tribler_executable
        self.code_port = args.code_port
        self._logger = logging.getLogger(self.__class__.__name__)
        self.allow_plain_downloads = args.plain
        self.magnets_file_path = args.magnetsfile
        self.pending_tasks = {}  # Dictionary of pending tasks
        self.probabilities = []
        self.socket_factory = TriblerCodeClientFactory(self)
        self.code_socket = None
        self.start_time = time.time()
        self.request_manager = HTTPRequestManager()
        self.irc_manager = None
        self.tribler_crashed = False
        self.download_monitor = None
        self.resource_monitor = None
        self.random_action_lc = None
        self.tribler_started_lc = None
        self.tribler_started_checks = 1
        self.tribler_stopped_lc = None
        self.tribler_stopped_checks = 1
        self.tribler_process = None
        self.shutting_down = False

        self.start_tribler()

        if args.duration:
            reactor.callLater(args.duration, self.stop, 0)
示例#2
0
    def __init__(self, interval):
        self.interval = interval
        self.request_manager = HTTPRequestManager()
        self.monitor_lc = LoopingCall(self.monitor_downloads)
        self.start_time = time.time()

        # Create the output directory if it does not exist yet
        output_dir = os.path.join(os.getcwd(), "output")
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        self.download_stats_file_path = os.path.join(output_dir, 'download_stats.csv')
        with open(self.download_stats_file_path, "w") as output_file:
            output_file.write("time,infohash,status,speed_up,speed_down,progress\n")
示例#3
0
    def __init__(self, args):
        self.tribler_path = args.tribler_executable
        self._logger = logging.getLogger(self.__class__.__name__)
        self.allow_plain_downloads = args.plain
        self.magnets_file_path = args.magnetsfile
        self.pending_tasks = {}  # Dictionary of pending tasks
        self.probabilities = []

        if not args.silent:
            self.random_action_lc = LoopingCall(self.perform_random_action)
            self.random_action_lc.start(15)
        else:
            # Trigger Tribler startup through a simple action
            self.execute_action(WaitAction(1000))

        self.check_task_completion_lc = LoopingCall(self.check_task_completion)
        self.check_task_completion_lc.start(2, now=False)

        self.check_crash_lc = LoopingCall(self.check_crash)
        self.check_crash_lc.start(11, now=False)

        self.start_time = time.time()
        self.request_manager = HTTPRequestManager()
        self.irc_manager = None
        self.tribler_crashed = False
        self.download_monitor = None

        if args.ircid:
            self.irc_manager = IRCManager(self, args.ircid)
            self.irc_manager.start()

        if args.duration:
            reactor.callLater(args.duration, self.stop, 0)

        if args.monitordownloads:
            self.download_monitor = DownloadMonitor(args.monitordownloads)
            reactor.callLater(20, self.download_monitor.start)

        if args.monitorresources:
            self.resource_monitor = ResourceMonitor(args.monitorresources)
            reactor.callLater(20, self.resource_monitor.start)

        # Determine probabilities
        with open(os.path.join(os.getcwd(), "data", "action_weights.txt"),
                  "r") as action_weights_file:
            content = action_weights_file.read()
            for line in content.split('\n'):
                if len(line) == 0:
                    continue

                if line.startswith('#'):
                    continue

                parts = line.split('=')
                if len(parts) < 2:
                    continue

                self.probabilities.append((parts[0], int(parts[1])))
    def __init__(self, interval):
        self.interval = interval
        self.request_manager = HTTPRequestManager()
        self.monitor_memory_lc = LoopingCall(self.monitor_memory)
        self.monitor_cpu_lc = LoopingCall(self.monitor_cpu)
        self.start_time = time.time()
        self.latest_memory_time = 0
        self.latest_cpu_time = 0

        # Create the output directory if it does not exist yet
        output_dir = os.path.join(os.getcwd(), "output")
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        self.memory_stats_file_path = os.path.join(output_dir, 'memory_stats.csv')
        with open(self.memory_stats_file_path, "w") as output_file:
            output_file.write("time,memory_usage\n")

        self.cpu_stats_file_path = os.path.join(output_dir, 'cpu_stats.csv')
        with open(self.cpu_stats_file_path, "w") as output_file:
            output_file.write("time,cpu_usage\n")
示例#5
0
class DownloadMonitor(object):
    """
    This class is responsible for monitoring downloads in Tribler.
    Specifically, it fetches information from the Tribler core and writes it to a file.
    """

    def __init__(self, interval):
        self.interval = interval
        self.request_manager = HTTPRequestManager()
        self.monitor_lc = LoopingCall(self.monitor_downloads)
        self.start_time = time.time()

        # Create the output directory if it does not exist yet
        output_dir = os.path.join(os.getcwd(), "output")
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        self.download_stats_file_path = os.path.join(output_dir, 'download_stats.csv')
        with open(self.download_stats_file_path, "w") as output_file:
            output_file.write("time,infohash,status,speed_up,speed_down,progress\n")

    def start(self):
        """
        Start the monitoring loop for the downloads.
        """
        self.monitor_lc.start(self.interval)

    def stop(self):
        """
        Stop the monitoring loop for the downloads.
        """
        if self.monitor_lc and self.monitor_lc.running:
            self.monitor_lc.stop()
            self.monitor_lc = None

    def on_downloads(self, response):
        downloads = json.loads(response)
        for download in downloads["downloads"]:
            with open(self.download_stats_file_path, "a") as output_file:
                time_diff = time.time() - self.start_time
                output_file.write("%s,%s,%s,%s,%s,%f\n" % (time_diff,
                                                           download["infohash"],
                                                           download["status"],
                                                           download["speed_up"],
                                                           download["speed_down"],
                                                           download["progress"]))

    def monitor_downloads(self):
        """
        Monitor the downloads in Tribler.
        """
        return self.request_manager.get_downloads().addCallback(self.on_downloads)
示例#6
0
    def __init__(self, args):
        self.tribler_path = args.tribler_executable
        self._logger = logging.getLogger(self.__class__.__name__)
        self.allow_plain_downloads = args.plain
        self.pending_tasks = {}  # Dictionary of pending tasks

        if not args.silent:
            self.random_action_lc = LoopingCall(self.perform_random_action)
            self.random_action_lc.start(15)
        else:
            # Trigger Tribler startup through a simple action
            self.execute_action(WaitAction(1000))

        self.check_task_completion_lc = LoopingCall(self.check_task_completion)
        self.check_task_completion_lc.start(2, now=False)

        self.check_crash_lc = LoopingCall(self.check_crash)
        self.check_crash_lc.start(11, now=False)

        self.start_time = time.time()
        self.request_manager = HTTPRequestManager()
        self.irc_manager = None
        self.tribler_crashed = False
        self.download_monitor = None

        if args.ircid:
            self.irc_manager = IRCManager(self, args.ircid)
            self.irc_manager.start()

        if args.duration:
            reactor.callLater(args.duration, self.stop, 0)

        if args.monitordownloads:
            self.download_monitor = DownloadMonitor(args.monitordownloads)
            reactor.callLater(20, self.download_monitor.start)

        if args.monitorresources:
            self.resource_monitor = ResourceMonitor(args.monitorresources)
            reactor.callLater(20, self.resource_monitor.start)
class ResourceMonitor(object):
    """
    This class is responsible for monitoring resources in Tribler.
    Specifically, it fetches information from the Tribler core and writes it to a file.
    """

    def __init__(self, interval):
        self.interval = interval
        self.request_manager = HTTPRequestManager()
        self.monitor_memory_lc = LoopingCall(self.monitor_memory)
        self.monitor_cpu_lc = LoopingCall(self.monitor_cpu)
        self.start_time = time.time()
        self.latest_memory_time = 0
        self.latest_cpu_time = 0

        # Create the output directory if it does not exist yet
        output_dir = os.path.join(os.getcwd(), "output")
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        self.memory_stats_file_path = os.path.join(output_dir, 'memory_stats.csv')
        with open(self.memory_stats_file_path, "w") as output_file:
            output_file.write("time,memory_usage\n")

        self.cpu_stats_file_path = os.path.join(output_dir, 'cpu_stats.csv')
        with open(self.cpu_stats_file_path, "w") as output_file:
            output_file.write("time,cpu_usage\n")

    def start(self):
        """
        Start the monitoring loop for the resources.
        """
        self.monitor_memory_lc.start(self.interval)
        self.monitor_cpu_lc.start(self.interval)

    def stop(self):
        """
        Stop the monitoring loop for the resources.
        """
        if self.monitor_memory_lc and self.monitor_memory_lc.running:
            self.monitor_memory_lc.stop()
            self.monitor_memory_lc = None

        if self.monitor_cpu_lc and self.monitor_cpu_lc.running:
            self.monitor_cpu_lc.stop()
            self.monitor_cpu_lc = None

    def on_memory_history(self, response):
        history = json.loads(response)
        for history_item in history["memory_history"]:
            if history_item["time"] > self.latest_memory_time:
                self.latest_memory_time = history_item["time"]
                time_diff = history_item["time"] - self.start_time
                with open(self.memory_stats_file_path, "a") as output_file:
                    output_file.write("%s,%s\n" % (time_diff, history_item["mem"]))

    def on_cpu_history(self, response):
        history = json.loads(response)
        for history_item in history["cpu_history"]:
            if history_item["time"] > self.latest_cpu_time:
                self.latest_cpu_time = history_item["time"]
                time_diff = history_item["time"] - self.start_time
                with open(self.cpu_stats_file_path, "a") as output_file:
                    output_file.write("%s,%s\n" % (time_diff, history_item["cpu"]))

    def monitor_memory(self):
        """
        Monitor the memory usage in Tribler.
        """
        return self.request_manager.get_memory_history_core().addCallback(self.on_memory_history)

    def monitor_cpu(self):
        """
        Monitor the CPU usage in Tribler.
        """
        return self.request_manager.get_cpu_history_core().addCallback(self.on_cpu_history)
示例#8
0
class Executor(object):
    def __init__(self, args):
        self.args = args
        self.tribler_path = args.tribler_executable
        self.code_port = args.code_port
        self._logger = logging.getLogger(self.__class__.__name__)
        self.allow_plain_downloads = args.plain
        self.magnets_file_path = args.magnetsfile
        self.pending_tasks = {}  # Dictionary of pending tasks
        self.probabilities = []
        self.socket_factory = TriblerCodeClientFactory(self)
        self.code_socket = None
        self.start_time = time.time()
        self.request_manager = HTTPRequestManager()
        self.irc_manager = None
        self.tribler_crashed = False
        self.download_monitor = None
        self.resource_monitor = None
        self.random_action_lc = None
        self.tribler_started_lc = None
        self.tribler_started_checks = 1
        self.tribler_stopped_lc = None
        self.tribler_stopped_checks = 1
        self.tribler_process = None
        self.shutting_down = False

        self.start_tribler()

        if args.duration:
            reactor.callLater(args.duration, self.stop, 0)

    def check_tribler(self):
        """
        Check the state of Tribler.
        """
        def on_state(_):
            # It seems Tribler is already running; open the socket
            self._logger.info("Tribler already running - opening socket")
            self.open_code_socket()

        def on_error(failure):
            # We got an error, check whether it is ConnectionRefused. If so, start Tribler
            if isinstance(failure.value, ConnectionRefusedError):
                self.start_tribler()

        self.request_manager.get_state().addCallbacks(on_state, on_error)

    def start_tribler(self):
        """
        Start Tribler if it has not been started yet.
        """
        self._logger.info("Tribler not running - starting it")
        self.tribler_process = subprocess.Popen(
            "%s --allow-code-injection --testnet" % self.tribler_path,
            shell=True)
        reactor.callLater(5, self.check_tribler_started)

    def check_tribler_started(self):
        self._logger.info("Checking whether Tribler has started (%d/10)",
                          self.tribler_started_checks)

        def on_response(started):
            if started:
                self.open_code_socket()
            elif self.tribler_started_checks == 10:
                self._logger.error(
                    "Tribler did not seem to start within reasonable time, bailing out"
                )
                self.shutdown_tester(1)
            else:
                self.tribler_started_checks += 1
                reactor.callLater(5, self.check_tribler_started)

        return self.request_manager.is_tribler_started().addCallback(
            on_response)

    def open_code_socket(self):
        self._logger.info("Opening Tribler code socket connection")
        reactor.connectTCP("localhost", 5500, self.socket_factory)

    def on_socket_ready(self, socket):
        self.code_socket = socket
        self.determine_probabilities()

        if self.args.ircid:
            self.irc_manager = IRCManager(self, self.args.ircid)
            self.irc_manager.start()

        if not self.args.silent:
            self.random_action_lc = LoopingCall(self.perform_random_action)
            self.random_action_lc.start(15)

        if self.args.monitordownloads:
            self.download_monitor = DownloadMonitor(self.args.monitordownloads)
            reactor.callLater(20, self.download_monitor.start)

        if self.args.monitorresources:
            self.resource_monitor = ResourceMonitor(self.args.monitorresources)
            reactor.callLater(20, self.resource_monitor.start)

    def on_socket_failed(self, failure):
        self._logger.error("Tribler code socket connection failed: %s",
                           failure)
        self.stop(1)

    def determine_probabilities(self):
        with open(os.path.join(os.getcwd(), "data", "action_weights.txt"),
                  "r") as action_weights_file:
            content = action_weights_file.read()
            for line in content.split('\n'):
                if len(line) == 0:
                    continue

                if line.startswith('#'):
                    continue

                parts = line.split('=')
                if len(parts) < 2:
                    continue

                self.probabilities.append((parts[0], int(parts[1])))

    def stop(self, exit_code):
        """
        Stop the application. First, shutdown Tribler (gracefully) and then shutdown the application tester.
        """
        if self.shutting_down:
            return

        self.shutting_down = True
        self._logger.info("About to shutdown Tribler")
        if self.download_monitor:
            self.download_monitor.stop()
            self.download_monitor = None
        if self.resource_monitor:
            self.resource_monitor.stop()
            self.resource_monitor = None
        if self.random_action_lc:
            self.random_action_lc.stop()
            self.random_action_lc = None

        if self.code_socket:
            self.execute_action(ShutdownAction())

        if sys.platform == "win32":
            os.system("taskkill /im tribler.exe")
        elif sys.platform == "darwin":
            os.kill(self.tribler_process.pid, signal.SIGINT)
        else:
            os.kill(self.tribler_process.pid, signal.SIGTERM)

        reactor.callLater(5, self.check_tribler_shutdown, exit_code)

    @inlineCallbacks
    def check_tribler_shutdown(self, exit_code):
        tribler_stopped = yield self.request_manager.is_tribler_stopped()
        if tribler_stopped:
            self.on_tribler_shutdown(exit_code)
        elif self.tribler_stopped_checks == 10:
            self._logger.warning(
                "Tribler did not shutdown in reasonable time; force kill it")
            if sys.platform == "win32":
                os.system("taskkill /im tribler.exe /f")
            else:
                os.kill(self.tribler_process.pid, signal.SIGKILL)
            self.on_tribler_shutdown(exit_code)
        else:
            # Still alive, schedule next check
            self.tribler_stopped_checks += 1
            reactor.callLater(5, self.check_tribler_shutdown, exit_code)

    def on_tribler_shutdown(self, exit_code):
        self._logger.info("Stopped Tribler, shutting down")
        self.shutdown_tester(exit_code)

    def shutdown_tester(self, exit_code):
        reactor.addSystemEventTrigger('after', 'shutdown', os._exit, exit_code)
        reactor.stop()

    @property
    def uptime(self):
        return time.time() - self.start_time

    def on_task_result(self, task_id, result):
        """
        A task has completed. Invoke the task completion callback with the result.
        """
        if task_id in self.pending_tasks:
            self.pending_tasks[task_id].callback(result)
            self.pending_tasks.pop(task_id, None)

    def on_tribler_crash(self, traceback):
        """
        Tribler has crashed. Handle the error and shut everything down.
        """
        self._logger.error("********** TRIBLER CRASHED **********")
        self._logger.error(
            "Tribler crashed after uptime of %s sec! Stack trace: %s",
            self.uptime, traceback)
        self.tribler_crashed = True
        if self.irc_manager:
            self.irc_manager.irc.send_channel_message(
                "Tribler crashed with stack trace: %s" % traceback)
        self.stop(1)

    def weighted_choice(self, choices):
        if len(choices) == 0:
            return None
        values, weights = zip(*choices)
        total = 0
        cum_weights = []
        for w in weights:
            total += w
            cum_weights.append(total)
        x = random() * total
        i = bisect(cum_weights, x)
        return values[i]

    def get_rand_bool(self):
        return randint(0, 1) == 0

    def execute_action(self, action):
        """
        Execute a given action and return a deferred that fires with the result of the action.
        """
        self._logger.info("Executing action: %s" % action)

        task_id = ''.join(choice('0123456789abcdef') for _ in xrange(10))
        task_deferred = Deferred()
        self.pending_tasks[task_id] = task_deferred

        code = """return_value = ''

def exit_script():
    import sys
    print 'Execution of task %s completed'
    sys.exit(0)\n\n""" % task_id

        code += action.generate_code() + '\nexit_script()'
        base64_code = code.encode('base64')

        # Let Tribler execute this code
        self.execute_code(base64_code, task_id)

        return task_deferred

    def execute_code(self, base64_code, task_id):
        self._logger.info("Executing code with task id: %s" % task_id)
        self.code_socket.run_code(base64_code, task_id)

    def perform_random_action(self):
        """
        This method performs a random action in Tribler.
        There are various actions possible that can occur with different probabilities.
        """
        action = self.weighted_choice(self.probabilities)
        if not action:
            self._logger.warning("No action available!")
            self.execute_action(WaitAction(1000))
            return
        self._logger.info("Performing action: %s", action)
        if action == 'random_page':
            action = RandomPageAction()
        elif action == 'search':
            action = RandomSearchAction()
        elif action == 'start_download':
            action = StartRandomDownloadAction(self.magnets_file_path)
        elif action == 'remove_download':
            action = RemoveRandomDownloadAction()
        elif action == 'explore_download':
            action = ExploreDownloadAction()
        elif action == 'browse_discovered':
            action = BrowseDiscoveredAction()
        elif action == 'explore_channel':
            action = ExploreChannelAction()
        elif action == 'screenshot':
            action = ScreenshotAction()
        elif action == 'start_vod':
            action = StartVODAction()
        elif action == 'change_anonymity':
            action = ChangeAnonymityAction(
                allow_plain=self.allow_plain_downloads)
        elif action == 'subscribe_unsubscribe':
            action = SubscribeUnsubscribeAction()

        self.execute_action(action)