Skip to content

Commit

Permalink
Switch to a port-hostname key
Browse files Browse the repository at this point in the history
  • Loading branch information
Wout Feys authored and willem-delbare committed Sep 20, 2024
1 parent 26bb6e8 commit 0a0aa1b
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 60 deletions.
35 changes: 12 additions & 23 deletions aikido_zen/background_process/hostnames.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,24 @@ def __init__(self, max_entries=200):

def add(self, hostname, port):
"""Add a hostname and port to the map"""
if self.length >= self.max_entries:
key = get_key(hostname, port)
if not self.map.get(key):
self.map[key] = {"hostname": hostname, "port": port, "hits": 0}
if len(self.map) > self.max_entries:
# Remove the first added hostname
first_added = next(iter(self.map))
ports = self.map[
first_added
] # Get the Ports object associated with the first key

if len(ports) > 1:
first_port = next(iter(ports))
ports.remove(first_port)
else:
del self.map[first_added]
if not self.map.get(hostname):
self.map[hostname] = set()
self.map[hostname].add(port)

@property
def length(self):
"""Gives length with ports as seperate entities"""
return sum(len(ports) for ports in self.map.values())
del self.map[first_added]
self.map[key]["hits"] += 1

def as_array(self):
"""Exports the contents as an array"""
return [
{"hostname": hostname, "port": port}
for hostname, ports in self.map.items()
for port in ports
]
return self.map.values()

def clear(self):
"""Clear the entire map"""
self.map.clear()


def get_key(hostname, port):
"""Returns a string key"""
return f"{hostname}:{port}"
80 changes: 43 additions & 37 deletions aikido_zen/background_process/hostnames_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,35 @@ def test_add_hostname():
"""Test adding a hostname."""
hostnames = Hostnames(max_entries=3)
hostnames.add("example.com", 80)
assert "example.com" in hostnames.map
assert hostnames.map["example.com"] == {80} # Should be a set
key = "example.com:80"
assert key in hostnames.map
assert hostnames.map[key]["hostname"] == "example.com"
assert hostnames.map[key]["port"] == 80
assert hostnames.map[key]["hits"] == 1


def test_add_multiple_ports():
"""Test adding multiple ports for the same hostname."""
hostnames = Hostnames(max_entries=3)
hostnames.add("example.com", 80)
hostnames.add("example.com", 443)
assert hostnames.map["example.com"] == {80, 443} # Should contain both ports

key80 = "example.com:80"
key443 = "example.com:443"

assert key80 in hostnames.map
assert key443 in hostnames.map
assert hostnames.map[key80]["hits"] == 1
assert hostnames.map[key443]["hits"] == 1


def test_add_duplicate_hostname():
"""Test adding a duplicate hostname."""
hostnames = Hostnames(max_entries=3)
hostnames.add("example.com", 80)
hostnames.add("example.com", 80) # Should not change the port
assert hostnames.map["example.com"] == {80}
key = "example.com:80"
assert hostnames.map[key]["hits"] == 2 # Hits should increment


def test_max_entries():
Expand All @@ -34,10 +45,10 @@ def test_max_entries():
hostnames.add("localhost", None)
hostnames.add("newsite.com", 8080) # This should remove "example.com"

assert "example.com" not in hostnames.map
assert "test.com" in hostnames.map
assert "localhost" in hostnames.map
assert "newsite.com" in hostnames.map
assert "example.com:80" not in hostnames.map
assert "test.com:443" in hostnames.map
assert "localhost:None" in hostnames.map
assert "newsite.com:8080" in hostnames.map
assert len(hostnames.map) == 3


Expand All @@ -47,10 +58,10 @@ def test_as_array():
hostnames.add("example.com", 80)
hostnames.add("test.com", 443)
expected_array = [
{"hostname": "example.com", "port": 80},
{"hostname": "test.com", "port": 443},
{"hostname": "example.com", "port": 80, "hits": 1},
{"hostname": "test.com", "port": 443, "hits": 1},
]
assert hostnames.as_array() == expected_array
assert list(hostnames.as_array()) == expected_array


def test_clear():
Expand All @@ -66,8 +77,11 @@ def test_add_none_port():
"""Test adding a hostname with a None port."""
hostnames = Hostnames(max_entries=3)
hostnames.add("example.com", None)
assert "example.com" in hostnames.map
assert None in hostnames.map["example.com"] # Should be in the set
key = "example.com:None"
assert key in hostnames.map
assert hostnames.map[key]["hostname"] == "example.com"
assert hostnames.map[key]["port"] is None
assert hostnames.map[key]["hits"] == 1


def test_exceed_max_entries_with_multiple_ports():
Expand All @@ -76,38 +90,33 @@ def test_exceed_max_entries_with_multiple_ports():
hostnames.add("example.com", 80)
hostnames.add("example.com", 443)
hostnames.add("test.com", 8080)
hostnames.add("newsite.com", 3000) # This should remove "example.com"
hostnames.add("newsite.com", 3000) # This should remove "example.com:80"

assert hostnames.map["example.com"] == {443}
assert "test.com" in hostnames.map
assert "newsite.com" in hostnames.map
assert "example.com:80" not in hostnames.map
assert "example.com:443" in hostnames.map
assert "test.com:8080" in hostnames.map
assert "newsite.com:3000" in hostnames.map
assert len(hostnames.map) == 3


def test_add_ports_and_check_length():
"""Test adding ports and checking the length property."""
hostnames = Hostnames(max_entries=5)
hostnames.add("example.com", 80)
hostnames.add("example.com", 443)
hostnames.add("test.com", 8080)

assert hostnames.length == 3 # 2 ports for example.com + 1 for test.com


def test_add_and_remove_ports():
"""Test adding and removing ports."""
hostnames = Hostnames(max_entries=3)
hostnames.add("example.com", 80)
assert hostnames.map["example.com"] == {80}
assert hostnames.map["example.com:80"]["hits"] == 1
hostnames.add("example.com", 443)
assert hostnames.map["example.com"] == {80, 443}
assert hostnames.map["example.com:80"]["hits"] == 1
assert hostnames.map["example.com:443"]["hits"] == 1
hostnames.add("test.com", 8080)
assert hostnames.map["example.com"] == {80, 443}
assert hostnames.map["test.com"] == {8080}
assert hostnames.map["example.com:80"]["hits"] == 1
assert hostnames.map["example.com:443"]["hits"] == 1
assert hostnames.map["test.com:8080"]["hits"] == 1

# Remove a port
hostnames.map["example.com"].remove(80)
assert hostnames.map["example.com"] == {443} # Should only have port 443
# Remove a port (not directly supported in the current implementation)
# This part of the test is not applicable since we don't have a remove method.
# Instead, we can just check the hits.
hostnames.map["example.com:80"]["hits"] = 0 # Simulating removal
assert hostnames.map["example.com:80"]["hits"] == 0 # Should only have port 443


def test_clear_with_multiple_entries():
Expand All @@ -118,6 +127,3 @@ def test_clear_with_multiple_entries():
hostnames.add("localhost", 3000)
hostnames.clear()
assert len(hostnames.map) == 0


# To run the tests, use the command: pytest <filename>.py

0 comments on commit 0a0aa1b

Please sign in to comment.