mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-17 14:14:22 +01:00
Adds new gatekeeper tests
This commit is contained in:
@@ -27,6 +27,7 @@ class UserInfo:
|
|||||||
self.available_slots = available_slots
|
self.available_slots = available_slots
|
||||||
self.subscription_expiry = subscription_expiry
|
self.subscription_expiry = subscription_expiry
|
||||||
|
|
||||||
|
# FIXME: this list is currently never wiped
|
||||||
if not appointments:
|
if not appointments:
|
||||||
self.appointments = []
|
self.appointments = []
|
||||||
else:
|
else:
|
||||||
@@ -139,17 +140,17 @@ class Gatekeeper:
|
|||||||
"""
|
"""
|
||||||
Updates (add/removes) slots from a user subscription.
|
Updates (add/removes) slots from a user subscription.
|
||||||
|
|
||||||
Slots are removed if a new subscription is given, or an update is given with a new subscription bigger than the
|
Slots are removed if a new appointment is given, or an update is given with an appointment bigger than the
|
||||||
old one.
|
old one.
|
||||||
|
|
||||||
Slots are added if an update is given but the new appointment is smaller than the old one.
|
Slots are added if an update is given but the new appointment is smaller than the old one.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
user_id(:obj:`str`): the public key that identifies the user (33-bytes hex str).
|
user_id(:obj:`str`): the public key that identifies the user (33-bytes hex str).
|
||||||
new_appointment (:obj:`ExtendedAppointment <teos.extended_appointment.ExtendedAppointment>`): the new
|
new_appointment (:obj:`dict`): the summary of new appointment the user is requesting
|
||||||
appointment the user is requesting to add.
|
to add.
|
||||||
old_appointment (:obj:`ExtendedAppointment <teos.extended_appointment.ExtendedAppointment>`): the old
|
old_appointment (:obj:`dict`): the summary old appointment the user wants to replace.
|
||||||
appointment the user wants to replace. Optional.
|
Optional.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`int`: the number of remaining appointment slots.
|
:obj:`int`: the number of remaining appointment slots.
|
||||||
@@ -180,7 +181,7 @@ class Gatekeeper:
|
|||||||
|
|
||||||
def get_expired_appointments(self, block_height):
|
def get_expired_appointments(self, block_height):
|
||||||
"""
|
"""
|
||||||
Gets a list of appointments that are expiring at a given block height.
|
Gets a list of appointments that expire at a given block height.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
block_height: the block height that wants to be checked.
|
block_height: the block height that wants to be checked.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Watcher:
|
|||||||
"""
|
"""
|
||||||
The :class:`Watcher` is in charge of watching for channel breaches for the appointments accepted by the tower.
|
The :class:`Watcher` is in charge of watching for channel breaches for the appointments accepted by the tower.
|
||||||
|
|
||||||
The :class:`Watcher` keeps track of the accepted appointments in ``appointments`` and, for new received block,
|
The :class:`Watcher` keeps track of the accepted appointments in ``appointments`` and, for new received blocks,
|
||||||
checks if any breach has happened by comparing the txids with the appointment locators. If a breach is seen, the
|
checks if any breach has happened by comparing the txids with the appointment locators. If a breach is seen, the
|
||||||
``encrypted_blob`` of the corresponding appointment is decrypted and the data is passed to the
|
``encrypted_blob`` of the corresponding appointment is decrypted and the data is passed to the
|
||||||
:obj:`Responder <teos.responder.Responder>`.
|
:obj:`Responder <teos.responder.Responder>`.
|
||||||
@@ -115,7 +115,7 @@ class Watcher:
|
|||||||
:obj:`AppointmentLimitReached`: If the tower cannot hold more appointments (cap reached).
|
:obj:`AppointmentLimitReached`: If the tower cannot hold more appointments (cap reached).
|
||||||
:obj:`AuthenticationFailure <teos.gatekeeper.AuthenticationFailure>`: If the user cannot be authenticated.
|
:obj:`AuthenticationFailure <teos.gatekeeper.AuthenticationFailure>`: If the user cannot be authenticated.
|
||||||
:obj:`NotEnoughSlots <teos.gatekeeper.NotEnoughSlots>`: If the user does not have enough available slots,
|
:obj:`NotEnoughSlots <teos.gatekeeper.NotEnoughSlots>`: If the user does not have enough available slots,
|
||||||
so the appointment is rejected
|
so the appointment is rejected.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if len(self.appointments) >= self.max_appointments:
|
if len(self.appointments) >= self.max_appointments:
|
||||||
@@ -129,6 +129,7 @@ class Watcher:
|
|||||||
# If an appointment is requested by the user the uuid can be recomputed and queried straightaway (no maps).
|
# If an appointment is requested by the user the uuid can be recomputed and queried straightaway (no maps).
|
||||||
uuid = hash_160("{}{}".format(appointment.locator, user_id))
|
uuid = hash_160("{}{}".format(appointment.locator, user_id))
|
||||||
|
|
||||||
|
# The third argument is the previous version of the same appointment (optional, returns None if missing)
|
||||||
available_slots = self.gatekeeper.update_available_slots(
|
available_slots = self.gatekeeper.update_available_slots(
|
||||||
user_id, appointment.get_summary(), self.appointments.get(uuid)
|
user_id, appointment.get_summary(), self.appointments.get(uuid)
|
||||||
)
|
)
|
||||||
@@ -140,6 +141,7 @@ class Watcher:
|
|||||||
if uuid not in self.locator_uuid_map[appointment.locator]:
|
if uuid not in self.locator_uuid_map[appointment.locator]:
|
||||||
self.locator_uuid_map[appointment.locator].append(uuid)
|
self.locator_uuid_map[appointment.locator].append(uuid)
|
||||||
else:
|
else:
|
||||||
|
# Otherwise two users have sent an appointment with the same locator, so we need to store both.
|
||||||
self.locator_uuid_map[appointment.locator] = [uuid]
|
self.locator_uuid_map[appointment.locator] = [uuid]
|
||||||
|
|
||||||
self.db_manager.store_watcher_appointment(uuid, appointment.to_dict())
|
self.db_manager.store_watcher_appointment(uuid, appointment.to_dict())
|
||||||
@@ -191,7 +193,7 @@ class Watcher:
|
|||||||
expired_appointments, self.appointments, self.locator_uuid_map, self.db_manager
|
expired_appointments, self.appointments, self.locator_uuid_map, self.db_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
valid_breaches, invalid_breaches = self.filter_valid_breaches(self.get_breaches(txids))
|
valid_breaches, invalid_breaches = self.filter_breaches(self.get_breaches(txids))
|
||||||
|
|
||||||
triggered_flags = []
|
triggered_flags = []
|
||||||
appointments_to_delete = []
|
appointments_to_delete = []
|
||||||
@@ -264,9 +266,9 @@ class Watcher:
|
|||||||
|
|
||||||
return breaches
|
return breaches
|
||||||
|
|
||||||
def filter_valid_breaches(self, breaches):
|
def filter_breaches(self, breaches):
|
||||||
"""
|
"""
|
||||||
Filters what of the found breaches contain valid transaction data.
|
Filters the valid from the invalid channel breaches.
|
||||||
|
|
||||||
The :obj:`Watcher` cannot if a given ``encrypted_blob`` contains a valid transaction until a breach if seen.
|
The :obj:`Watcher` cannot if a given ``encrypted_blob`` contains a valid transaction until a breach if seen.
|
||||||
Blobs that contain arbitrary data are dropped and not sent to the :obj:`Responder <teos.responder.Responder>`.
|
Blobs that contain arbitrary data are dropped and not sent to the :obj:`Responder <teos.responder.Responder>`.
|
||||||
|
|||||||
@@ -41,6 +41,14 @@ def test_init_appointment(appointment_data):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_summary(appointment_data):
|
||||||
|
assert ExtendedAppointment.from_dict(appointment_data).get_summary() == {
|
||||||
|
"locator": appointment_data["locator"],
|
||||||
|
"user_id": appointment_data["user_id"],
|
||||||
|
"size": len(appointment_data["encrypted_blob"]),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_from_dict(appointment_data):
|
def test_from_dict(appointment_data):
|
||||||
# The appointment should be build if we don't miss any field
|
# The appointment should be build if we don't miss any field
|
||||||
appointment = ExtendedAppointment.from_dict(appointment_data)
|
appointment = ExtendedAppointment.from_dict(appointment_data)
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from teos.gatekeeper import AuthenticationFailure, NotEnoughSlots
|
from teos.users_dbm import UsersDBM
|
||||||
|
from teos.block_processor import BlockProcessor
|
||||||
|
from teos.gatekeeper import AuthenticationFailure, NotEnoughSlots, UserInfo
|
||||||
|
|
||||||
from common.cryptographer import Cryptographer
|
from common.cryptographer import Cryptographer
|
||||||
from common.exceptions import InvalidParameter
|
from common.exceptions import InvalidParameter
|
||||||
|
from common.constants import ENCRYPTED_BLOB_MAX_SIZE_HEX
|
||||||
|
|
||||||
from test.teos.unit.conftest import get_random_value_hex, generate_keypair, get_config
|
from test.teos.unit.conftest import get_random_value_hex, generate_keypair, get_config, generate_dummy_appointment
|
||||||
|
|
||||||
|
|
||||||
config = get_config()
|
config = get_config()
|
||||||
@@ -13,11 +16,18 @@ config = get_config()
|
|||||||
|
|
||||||
def test_init(gatekeeper, run_bitcoind):
|
def test_init(gatekeeper, run_bitcoind):
|
||||||
assert isinstance(gatekeeper.default_slots, int) and gatekeeper.default_slots == config.get("DEFAULT_SLOTS")
|
assert isinstance(gatekeeper.default_slots, int) and gatekeeper.default_slots == config.get("DEFAULT_SLOTS")
|
||||||
|
assert isinstance(
|
||||||
|
gatekeeper.default_subscription_duration, int
|
||||||
|
) and gatekeeper.default_subscription_duration == config.get("DEFAULT_SUBSCRIPTION_DURATION")
|
||||||
|
assert isinstance(gatekeeper.expiry_delta, int) and gatekeeper.expiry_delta == config.get("EXPIRY_DELTA")
|
||||||
|
assert isinstance(gatekeeper.block_processor, BlockProcessor)
|
||||||
|
assert isinstance(gatekeeper.user_db, UsersDBM)
|
||||||
assert isinstance(gatekeeper.registered_users, dict) and len(gatekeeper.registered_users) == 0
|
assert isinstance(gatekeeper.registered_users, dict) and len(gatekeeper.registered_users) == 0
|
||||||
|
|
||||||
|
|
||||||
def test_add_update_user(gatekeeper):
|
def test_add_update_user(gatekeeper):
|
||||||
# add_update_user adds DEFAULT_SLOTS to a given user as long as the identifier is {02, 03}| 32-byte hex str
|
# add_update_user adds DEFAULT_SLOTS to a given user as long as the identifier is {02, 03}| 32-byte hex str
|
||||||
|
# it also add DEFAULT_SUBSCRIPTION_DURATION + current_block_height to the user
|
||||||
user_pk = "02" + get_random_value_hex(32)
|
user_pk = "02" + get_random_value_hex(32)
|
||||||
|
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
@@ -27,6 +37,11 @@ def test_add_update_user(gatekeeper):
|
|||||||
gatekeeper.add_update_user(user_pk)
|
gatekeeper.add_update_user(user_pk)
|
||||||
|
|
||||||
assert gatekeeper.registered_users.get(user_pk).available_slots == current_slots + config.get("DEFAULT_SLOTS")
|
assert gatekeeper.registered_users.get(user_pk).available_slots == current_slots + config.get("DEFAULT_SLOTS")
|
||||||
|
assert gatekeeper.registered_users[
|
||||||
|
user_pk
|
||||||
|
].subscription_expiry == gatekeeper.block_processor.get_block_count() + config.get(
|
||||||
|
"DEFAULT_SUBSCRIPTION_DURATION"
|
||||||
|
)
|
||||||
|
|
||||||
# The same can be checked for multiple users
|
# The same can be checked for multiple users
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
@@ -35,6 +50,11 @@ def test_add_update_user(gatekeeper):
|
|||||||
|
|
||||||
gatekeeper.add_update_user(user_pk)
|
gatekeeper.add_update_user(user_pk)
|
||||||
assert gatekeeper.registered_users.get(user_pk).available_slots == config.get("DEFAULT_SLOTS")
|
assert gatekeeper.registered_users.get(user_pk).available_slots == config.get("DEFAULT_SLOTS")
|
||||||
|
assert gatekeeper.registered_users[
|
||||||
|
user_pk
|
||||||
|
].subscription_expiry == gatekeeper.block_processor.get_block_count() + config.get(
|
||||||
|
"DEFAULT_SUBSCRIPTION_DURATION"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_add_update_user_wrong_pk(gatekeeper):
|
def test_add_update_user_wrong_pk(gatekeeper):
|
||||||
@@ -108,4 +128,63 @@ def test_identify_user_wrong(gatekeeper):
|
|||||||
gatekeeper.authenticate_user(message, signature.encode())
|
gatekeeper.authenticate_user(message, signature.encode())
|
||||||
|
|
||||||
|
|
||||||
# FIXME: MISSING TESTS
|
def test_update_available_slots(gatekeeper):
|
||||||
|
# update_available_slots should decrease the slot count if a new appointment is added
|
||||||
|
# let's add a new user
|
||||||
|
sk, pk = generate_keypair()
|
||||||
|
compressed_pk = Cryptographer.get_compressed_pk(pk)
|
||||||
|
gatekeeper.add_update_user(compressed_pk)
|
||||||
|
|
||||||
|
# And now update the slots given an appointment
|
||||||
|
appointment, _ = generate_dummy_appointment()
|
||||||
|
gatekeeper.update_available_slots(compressed_pk, appointment.get_summary())
|
||||||
|
|
||||||
|
# This is a standard size appointment, so it should have reduced the slots by one
|
||||||
|
assert gatekeeper.registered_users[compressed_pk].available_slots == config.get("DEFAULT_SLOTS") - 1
|
||||||
|
|
||||||
|
# Updates can leave the count as it, decrease it, or increase it, depending on the appointment size (modulo
|
||||||
|
# ENCRYPTED_BLOB_MAX_SIZE_HEX)
|
||||||
|
|
||||||
|
# Appointments of the same size leave it as is
|
||||||
|
appointment_same_size, _ = generate_dummy_appointment()
|
||||||
|
remaining_slots = gatekeeper.update_available_slots(
|
||||||
|
compressed_pk, appointment.get_summary(), appointment_same_size.get_summary()
|
||||||
|
)
|
||||||
|
assert remaining_slots == config.get("DEFAULT_SLOTS") - 1
|
||||||
|
|
||||||
|
# Bigger appointments decrease it
|
||||||
|
appointment_x2_size = appointment_same_size
|
||||||
|
appointment_x2_size.encrypted_blob = "A" * (ENCRYPTED_BLOB_MAX_SIZE_HEX + 1)
|
||||||
|
remaining_slots = gatekeeper.update_available_slots(
|
||||||
|
compressed_pk, appointment_x2_size.get_summary(), appointment.get_summary()
|
||||||
|
)
|
||||||
|
assert remaining_slots == config.get("DEFAULT_SLOTS") - 2
|
||||||
|
|
||||||
|
# Smaller appointments increase it (using the same data but flipped)
|
||||||
|
remaining_slots = gatekeeper.update_available_slots(
|
||||||
|
compressed_pk, appointment.get_summary(), appointment_x2_size.get_summary()
|
||||||
|
)
|
||||||
|
assert remaining_slots == config.get("DEFAULT_SLOTS") - 1
|
||||||
|
|
||||||
|
# If the appointment needs more slots than there's free, it should fail
|
||||||
|
gatekeeper.registered_users[compressed_pk].available_slots = 1
|
||||||
|
with pytest.raises(NotEnoughSlots):
|
||||||
|
gatekeeper.update_available_slots(compressed_pk, appointment_x2_size.get_summary())
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_expired_appointments(gatekeeper):
|
||||||
|
# get_expired_appointments returns a list of appointment uuids expiring at a given block
|
||||||
|
|
||||||
|
appointment = {}
|
||||||
|
# Let's simulate adding some users with dummy expiry times
|
||||||
|
gatekeeper.registered_users = {}
|
||||||
|
for i in reversed(range(100)):
|
||||||
|
uuid = get_random_value_hex(16)
|
||||||
|
user_appointments = [get_random_value_hex(16)]
|
||||||
|
# Add a single appointment to the user
|
||||||
|
gatekeeper.registered_users[uuid] = UserInfo(100, i, user_appointments)
|
||||||
|
appointment[i] = user_appointments
|
||||||
|
|
||||||
|
# Now let's check that reversed
|
||||||
|
for i in range(100):
|
||||||
|
assert gatekeeper.get_expired_appointments(i + gatekeeper.expiry_delta) == appointment[i]
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ from teos.carrier import Carrier
|
|||||||
from teos.tools import bitcoin_cli
|
from teos.tools import bitcoin_cli
|
||||||
from teos.responder import Responder
|
from teos.responder import Responder
|
||||||
from teos.gatekeeper import UserInfo
|
from teos.gatekeeper import UserInfo
|
||||||
from teos.gatekeeper import Gatekeeper
|
|
||||||
from teos.chain_monitor import ChainMonitor
|
from teos.chain_monitor import ChainMonitor
|
||||||
from teos.appointments_dbm import AppointmentsDBM
|
from teos.appointments_dbm import AppointmentsDBM
|
||||||
from teos.block_processor import BlockProcessor
|
from teos.block_processor import BlockProcessor
|
||||||
from teos.watcher import Watcher, AppointmentLimitReached
|
from teos.watcher import Watcher, AppointmentLimitReached
|
||||||
|
from teos.gatekeeper import Gatekeeper, AuthenticationFailure, NotEnoughSlots
|
||||||
|
|
||||||
from common.tools import compute_locator
|
from common.tools import compute_locator
|
||||||
from common.cryptographer import Cryptographer
|
from common.cryptographer import Cryptographer
|
||||||
@@ -95,13 +95,38 @@ def test_init(run_bitcoind, watcher):
|
|||||||
assert isinstance(watcher.appointments, dict) and len(watcher.appointments) == 0
|
assert isinstance(watcher.appointments, dict) and len(watcher.appointments) == 0
|
||||||
assert isinstance(watcher.locator_uuid_map, dict) and len(watcher.locator_uuid_map) == 0
|
assert isinstance(watcher.locator_uuid_map, dict) and len(watcher.locator_uuid_map) == 0
|
||||||
assert watcher.block_queue.empty()
|
assert watcher.block_queue.empty()
|
||||||
|
assert isinstance(watcher.db_manager, AppointmentsDBM)
|
||||||
|
assert isinstance(watcher.gatekeeper, Gatekeeper)
|
||||||
assert isinstance(watcher.block_processor, BlockProcessor)
|
assert isinstance(watcher.block_processor, BlockProcessor)
|
||||||
assert isinstance(watcher.responder, Responder)
|
assert isinstance(watcher.responder, Responder)
|
||||||
assert isinstance(watcher.max_appointments, int)
|
assert isinstance(watcher.max_appointments, int)
|
||||||
assert isinstance(watcher.gatekeeper, Gatekeeper)
|
|
||||||
assert isinstance(watcher.signing_key, PrivateKey)
|
assert isinstance(watcher.signing_key, PrivateKey)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_appointment_non_registered(watcher):
|
||||||
|
# Appointments from non-registered users should fail
|
||||||
|
user_sk, user_pk = generate_keypair()
|
||||||
|
|
||||||
|
appointment, dispute_tx = generate_dummy_appointment()
|
||||||
|
appointment_signature = Cryptographer.sign(appointment.serialize(), user_sk)
|
||||||
|
|
||||||
|
with pytest.raises(AuthenticationFailure, match="User not found"):
|
||||||
|
watcher.add_appointment(appointment, appointment_signature)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_appointment_no_slots(watcher):
|
||||||
|
# Appointments from register users with no available slots should aso fail
|
||||||
|
user_sk, user_pk = generate_keypair()
|
||||||
|
user_id = Cryptographer.get_compressed_pk(user_pk)
|
||||||
|
watcher.gatekeeper.registered_users[user_id] = UserInfo(available_slots=0, subscription_expiry=10)
|
||||||
|
|
||||||
|
appointment, dispute_tx = generate_dummy_appointment()
|
||||||
|
appointment_signature = Cryptographer.sign(appointment.serialize(), user_sk)
|
||||||
|
|
||||||
|
with pytest.raises(NotEnoughSlots):
|
||||||
|
watcher.add_appointment(appointment, appointment_signature)
|
||||||
|
|
||||||
|
|
||||||
def test_add_appointment(watcher):
|
def test_add_appointment(watcher):
|
||||||
# Simulate the user is registered
|
# Simulate the user is registered
|
||||||
user_sk, user_pk = generate_keypair()
|
user_sk, user_pk = generate_keypair()
|
||||||
@@ -184,7 +209,7 @@ def test_do_watch(watcher, temp_db_manager):
|
|||||||
watcher.appointments = {}
|
watcher.appointments = {}
|
||||||
watcher.gatekeeper.registered_users = {}
|
watcher.gatekeeper.registered_users = {}
|
||||||
|
|
||||||
# Simulate a register
|
# Simulate a register (times out in 10 bocks)
|
||||||
user_id = get_random_value_hex(16)
|
user_id = get_random_value_hex(16)
|
||||||
watcher.gatekeeper.registered_users[user_id] = UserInfo(
|
watcher.gatekeeper.registered_users[user_id] = UserInfo(
|
||||||
available_slots=100, subscription_expiry=watcher.block_processor.get_block_count() + 10
|
available_slots=100, subscription_expiry=watcher.block_processor.get_block_count() + 10
|
||||||
@@ -215,6 +240,8 @@ def test_do_watch(watcher, temp_db_manager):
|
|||||||
|
|
||||||
assert len(watcher.appointments) == 0
|
assert len(watcher.appointments) == 0
|
||||||
|
|
||||||
|
# FIXME: We should also add cases where the transactions are invalid. bitcoind_mock needs to be extended for this.
|
||||||
|
|
||||||
|
|
||||||
def test_get_breaches(watcher, txids, locator_uuid_map):
|
def test_get_breaches(watcher, txids, locator_uuid_map):
|
||||||
watcher.locator_uuid_map = locator_uuid_map
|
watcher.locator_uuid_map = locator_uuid_map
|
||||||
@@ -235,7 +262,7 @@ def test_get_breaches_random_data(watcher, locator_uuid_map):
|
|||||||
assert len(potential_breaches) == 0
|
assert len(potential_breaches) == 0
|
||||||
|
|
||||||
|
|
||||||
def test_filter_valid_breaches_random_data(watcher):
|
def test_filter_breaches_random_data(watcher):
|
||||||
appointments = {}
|
appointments = {}
|
||||||
locator_uuid_map = {}
|
locator_uuid_map = {}
|
||||||
breaches = {}
|
breaches = {}
|
||||||
@@ -256,7 +283,7 @@ def test_filter_valid_breaches_random_data(watcher):
|
|||||||
watcher.locator_uuid_map = locator_uuid_map
|
watcher.locator_uuid_map = locator_uuid_map
|
||||||
watcher.appointments = appointments
|
watcher.appointments = appointments
|
||||||
|
|
||||||
valid_breaches, invalid_breaches = watcher.filter_valid_breaches(breaches)
|
valid_breaches, invalid_breaches = watcher.filter_breaches(breaches)
|
||||||
|
|
||||||
# We have "triggered" TEST_SET_SIZE/2 breaches, all of them invalid.
|
# We have "triggered" TEST_SET_SIZE/2 breaches, all of them invalid.
|
||||||
assert len(valid_breaches) == 0 and len(invalid_breaches) == TEST_SET_SIZE / 2
|
assert len(valid_breaches) == 0 and len(invalid_breaches) == TEST_SET_SIZE / 2
|
||||||
@@ -289,7 +316,7 @@ def test_filter_valid_breaches(watcher):
|
|||||||
|
|
||||||
watcher.locator_uuid_map = locator_uuid_map
|
watcher.locator_uuid_map = locator_uuid_map
|
||||||
|
|
||||||
valid_breaches, invalid_breaches = watcher.filter_valid_breaches(breaches)
|
valid_breaches, invalid_breaches = watcher.filter_breaches(breaches)
|
||||||
|
|
||||||
# We have "triggered" a single breach and it was valid.
|
# We have "triggered" a single breach and it was valid.
|
||||||
assert len(invalid_breaches) == 0 and len(valid_breaches) == 1
|
assert len(invalid_breaches) == 0 and len(valid_breaches) == 1
|
||||||
|
|||||||
Reference in New Issue
Block a user