Skip to content
This repository has been archived by the owner on Sep 14, 2020. It is now read-only.

Fix on-field handler selection when a field is longer/equal to a diff #340

Merged
merged 1 commit into from
Apr 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion kopf/reactor/registries.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,9 @@ def _matches_field(
return (ignore_fields or
not isinstance(handler, handlers.ResourceChangingHandler) or
not handler.field or
any(field[:len(handler.field)] == handler.field for field in changed_fields))
any(changed_field[:len(handler.field)] == handler.field or # a.b.c -vs- a.b => ignore c
changed_field == handler.field[:len(changed_field)] # a.b -vs- a.b.c => ignore c
for changed_field in changed_fields))


def _matches_labels(
Expand Down
45 changes: 45 additions & 0 deletions tests/registries/test_handler_matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from kopf.reactor.causation import ResourceChangingCause
from kopf.structs.bodies import Body
from kopf.structs.dicts import parse_field
from kopf.structs.diffs import DiffOperation, DiffItem
mnarodovitch marked this conversation as resolved.
Show resolved Hide resolved
from kopf.structs.filters import MetaFilterToken
from kopf.structs.handlers import ResourceChangingHandler, Reason, ALL_REASONS

Expand Down Expand Up @@ -667,6 +668,50 @@ def some_fn(**_): ...
handlers = registry.resource_changing_handlers[cause.resource].get_handlers(cause)
assert not handlers


#
# Special case for nested fields with shorter/longer diffs.
#

def test_field_same_as_diff(cause_with_diff, registry, resource):

@kopf.on.field(resource.group, resource.version, resource.plural, registry=registry,
field='level1.level2')
def some_fn(**_): ...

cause = cause_with_diff
cause.reason = Reason.UPDATE
cause.diff = [DiffItem(DiffOperation.CHANGE, ('level1', 'level2'), 'old', 'new')]
handlers = registry.resource_changing_handlers[cause.resource].get_handlers(cause)
assert handlers


def test_field_longer_than_diff(cause_with_diff, registry, resource):

@kopf.on.field(resource.group, resource.version, resource.plural, registry=registry,
field='level1.level2.level3')
def some_fn(**_): ...

cause = cause_with_diff
cause.reason = Reason.UPDATE
cause.diff = [DiffItem(DiffOperation.CHANGE, ('level1', 'level2'), 'old', 'new')]
handlers = registry.resource_changing_handlers[cause.resource].get_handlers(cause)
assert handlers


def test_field_shorter_than_diff(cause_with_diff, registry, resource):

@kopf.on.field(resource.group, resource.version, resource.plural, registry=registry,
field='level1')
def some_fn(**_): ...

cause = cause_with_diff
cause.reason = Reason.UPDATE
cause.diff = [DiffItem(DiffOperation.CHANGE, ('level1', 'level2'), 'old', 'new')]
handlers = registry.resource_changing_handlers[cause.resource].get_handlers(cause)
assert handlers


#
# The handlers must be returned in order of registration,
# even if they are mixed with-/without- * -event/-field handlers.
Expand Down