Skip to content

Commit

Permalink
Clean up code and address codacy issues
Browse files Browse the repository at this point in the history
  • Loading branch information
xoriole committed Sep 14, 2022
1 parent 4dd3c88 commit b6289b0
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from tribler.core.components.popularity.community.payload import TorrentsHealthPayload, PopularTorrentsRequest
from tribler.core.components.popularity.community.version_community_mixin import VersionCommunityMixin
from tribler.core.utilities.unicode import hexlify
from tribler.core.utilities.utilities import get_normally_distributed_number, get_normally_distributed_positive_integers
from tribler.core.utilities.utilities import get_normally_distributed_positive_integers


class PopularityCommunity(RemoteQueryCommunity, VersionCommunityMixin):
Expand All @@ -20,7 +20,7 @@ class PopularityCommunity(RemoteQueryCommunity, VersionCommunityMixin):
Push:
- Every 5 seconds it gossips 10 random torrents to a random peer.
Pull:
- Everytime it receives an introduction request, it sends a request
- Every time it receives an introduction request, it sends a request
to return their popular torrents.
Gossiping is for checked torrents only.
Expand All @@ -46,7 +46,7 @@ def __init__(self, *args, torrent_checker=None, **kwargs):
# Init version community message handlers
self.init_version_community()

def introduction_request_callback(self, peer, dist, payload):
def introduction_request_callback(self, peer, _dist, _payload):
# Send request to peer to send popular torrents
self.ez_send(peer, PopularTorrentsRequest())

Expand Down Expand Up @@ -93,20 +93,20 @@ def process_torrents_health(self, torrent_healths):

@lazy_wrapper(PopularTorrentsRequest)
async def on_popular_torrents_request(self, peer, payload):
self.logger.debug(f"Received popular torrents health request")
self.logger.debug("Received popular torrents health request")
popular_torrents = self.get_likely_popular_torrents()
self.ez_send(peer, TorrentsHealthPayload.create({}, popular_torrents))

def get_likely_popular_torrents(self):
checked_and_alive = list(self.get_alive_checked_torrents())
checked_and_alive = self.get_alive_checked_torrents()
if not checked_and_alive:
return {}

num_torrents = len(checked_and_alive)
num_torrents_to_send = min(PopularityCommunity.GOSSIP_RANDOM_TORRENT_COUNT, num_torrents)
likely_popular_indices = self._get_likely_popular_indices(num_torrents_to_send, num_torrents)

sorted_torrents = sorted(checked_and_alive, key=lambda t: -t[1])
sorted_torrents = sorted(list(checked_and_alive), key=lambda t: -t[1])
likely_popular_torrents = {sorted_torrents[i] for i in likely_popular_indices}
return likely_popular_torrents

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import logging
import time
from functools import reduce
from random import randint
from types import SimpleNamespace
from typing import Set, Tuple
from unittest.mock import Mock

Expand All @@ -12,8 +9,6 @@

from pony.orm import db_session

import pytest

from tribler.core.components.metadata_store.db.store import MetadataStore
from tribler.core.components.metadata_store.remote_query_community.settings import RemoteQueryCommunitySettings
from tribler.core.components.popularity.community.popularity_community import PopularityCommunity
Expand All @@ -22,18 +17,25 @@
from tribler.core.utilities.utilities import random_infohash


def _generate_single_checked_torrent(status: str = 'alive') -> Tuple:
def get_seeders(status):
return 0 if status == 'dead' else randint(1, 10) if status == 'alive' else randint(11, 100)

def get_leechers(status):
return 0 if status == 'dead' else randint(1, 10) if status == 'alive' else randint(11, 100)
def _generate_single_checked_torrent(status: str = None) -> Tuple:
"""
Assumptions
DEAD -> peers: 0
POPULAR -> Peers: [101, 1000]
DEFAULT -> peers: [1, 100] # alive
"""
def get_peers_for(health_status):
if health_status == 'DEAD':
return 0
if health_status == 'POPULAR':
return randint(101, 1000)
return randint(1, 100)

# checked torrent structure is (infohash, seeders, leechers, last_check)
return random_infohash(), get_seeders(status), get_leechers(status), int(time.time())
return random_infohash(), get_peers_for(status), get_peers_for(status), int(time.time())


def _generate_checked_torrents(count: int, status: str = 'alive') -> Set:
def _generate_checked_torrents(count: int, status: str = None) -> Set:
return {_generate_single_checked_torrent(status) for _ in range(count)}


Expand Down Expand Up @@ -105,40 +107,35 @@ async def test_torrents_health_gossip(self):
assert torrent.last_check == checked_torrent_info[3]

def test_get_alive_torrents(self):
dead_torrents = _generate_checked_torrents(100, 'dead')
alive_torrents = _generate_checked_torrents(100, 'alive')
top_popular_torrents = _generate_checked_torrents(100, 'popular')
dead_torrents = _generate_checked_torrents(100, 'DEAD')
popular_torrents = _generate_checked_torrents(100, 'POPULAR')
alive_torrents = _generate_checked_torrents(100)

all_checked_torrents = dead_torrents | alive_torrents | top_popular_torrents
all_checked_torrents = dead_torrents | alive_torrents | popular_torrents
self.nodes[0].overlay.torrent_checker.torrents_checked.update(all_checked_torrents)

actual_alive_torrents = self.nodes[0].overlay.get_alive_checked_torrents()
assert len(actual_alive_torrents) == len(alive_torrents | top_popular_torrents)
assert len(actual_alive_torrents) == len(alive_torrents | popular_torrents)

async def test_torrents_health_gossip_multiple(self):
"""
Test whether torrent health information is correctly gossiped around
"""
dead_torrents = _generate_checked_torrents(100, 'dead')
alive_torrents = _generate_checked_torrents(100, 'alive')
top_popular_torrents = _generate_checked_torrents(100, 'popular')
dead_torrents = _generate_checked_torrents(100, 'DEAD')
popular_torrents = _generate_checked_torrents(100, 'POPULAR')
alive_torrents = _generate_checked_torrents(100)

all_checked_torrents = dead_torrents | alive_torrents | top_popular_torrents
all_checked_torrents = dead_torrents | alive_torrents | popular_torrents

node0_db = self.nodes[0].overlay.mds.TorrentState
node1_db = self.nodes[1].overlay.mds.TorrentState

node0_db_last_count = 0
node1_db_last_count = 0

# Given, initially there are no torrents in the database
with db_session:
node0_count = node0_db.select().count()
node1_count = node1_db.select().count()
assert node0_count == 0
assert node1_count == 0
node0_db_last_count = node0_count
node1_db_last_count = node1_count

# Setup, node 0 checks some torrents, both dead and alive (including popular ones).
self.nodes[0].overlay.torrent_checker.torrents_checked.update(all_checked_torrents)
Expand All @@ -151,9 +148,10 @@ async def test_torrents_health_gossip_multiple(self):
with db_session:
node0_count = node0_db.select().count()
node1_count = node1_db.select().count()

assert node0_count == 0 # Nothing received from Node 1 because it hasn't checked anything to share.
assert node1_count == PopularityCommunity.GOSSIP_POPULAR_TORRENT_COUNT
node0_db_last_count = node0_count

node1_db_last_count = node1_count

# Now, assuming Node 0 gossips random torrents to Node 1 multiple times to simulate periodic nature
Expand All @@ -167,10 +165,10 @@ async def test_torrents_health_gossip_multiple(self):
with db_session:
node0_count = node0_db.select().count()
node1_count = node1_db.select().count()

assert node0_count == 0 # Still nothing received from Node 1 because it hasn't checked torrents
assert node1_count >= node1_db_last_count

node0_db_last_count = node0_count
node1_db_last_count = node1_count

async def test_torrents_health_update(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def random_infohash():

# Now check that two stale torrents selected for check
selected_torrents = torrent_checker.check_local_torrents()
assert len(selected_torrents) == 2
assert 1 <= len(selected_torrents) <= 2


@db_session
Expand Down
8 changes: 5 additions & 3 deletions src/tribler/core/utilities/tests/test_utilities.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import logging
import random
from unittest.mock import MagicMock, patch

from aiohttp import ClientSession

import pytest
from scipy.stats import kstest, shapiro
from scipy.stats import shapiro

from tribler.core.logger.logger import load_logger_config
from tribler.core.utilities.patch_import import patch_import
Expand Down Expand Up @@ -281,5 +280,8 @@ def test_get_normally_distributed_positive_integers():
assert len(set(random_integer_numbers)) == len(random_integer_numbers)

# check if all numbers are integers and positive
is_positive_and_unique = all([number >= 0 and isinstance(number, int) for number in random_integer_numbers])
is_positive_and_unique = all(number >= 0 and isinstance(number, int) for number in random_integer_numbers)
assert is_positive_and_unique

with pytest.raises(ValueError):
_ = get_normally_distributed_positive_integers(size=11, limit=10)
2 changes: 1 addition & 1 deletion src/tribler/core/utilities/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def get_normally_distributed_positive_integers(size=1, limit=100) -> list:
Returns a list of non-repeated integer numbers based on normal distribution with mean value zero.
"""
if size > limit:
raise Exception("Cannot more numbers than the limit")
raise ValueError("Cannot more numbers than the limit")

numbers = []
while len(numbers) < size:
Expand Down

0 comments on commit b6289b0

Please sign in to comment.