Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Automatically discover new signals.py files in tests #181

Merged
merged 1 commit into from
Feb 3, 2023
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
14 changes: 8 additions & 6 deletions openedx_events/event_bus/avro/tests/test_avro.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@

from opaque_keys.edx.keys import CourseKey, UsageKey

# Each new folder with signals must be manually imported in order for the signals to be cached
# and used in the unit tests. Using 'disable=reimported' with pylint will work,
# because we just use the cached signal list.
from openedx_events.content_authoring import signals # pylint: disable=unused-import
from openedx_events.event_bus.avro.deserializer import AvroSignalDeserializer
from openedx_events.event_bus.avro.serializer import AvroSignalSerializer
from openedx_events.event_bus.avro.tests.test_utilities import (
Expand All @@ -20,8 +16,7 @@
deserialize_bytes_to_event_data,
serialize_event_data_to_bytes,
)
from openedx_events.learning import signals # See note above; pylint: disable=reimported
from openedx_events.tests.utils import FreezeSignalCacheMixin
from openedx_events.tests.utils import FreezeSignalCacheMixin, load_all_signals
from openedx_events.tooling import OpenEdxPublicSignal

# If a signal is explicitly not for use with the event bus, add it to this list
Expand Down Expand Up @@ -71,6 +66,13 @@ def generate_test_event_data_for_data_type(data_type):

class TestAvro(FreezeSignalCacheMixin, TestCase):
"""Tests for end-to-end serialization and deserialization of events"""

@classmethod
def setUpClass(cls):
super().setUpClass()
# Ensure we can usefully call all_events()
load_all_signals()

def test_all_events(self):
for signal in OpenEdxPublicSignal.all_events():
if signal.event_type in KNOWN_UNSERIALIZABLE_SIGNALS:
Expand Down
32 changes: 32 additions & 0 deletions openedx_events/tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""
Utils used by Open edX event tests.
"""
import pkgutil
from importlib import import_module

from openedx_events.tooling import OpenEdxPublicSignal


Expand Down Expand Up @@ -124,3 +127,32 @@ def start_events_isolation(cls):
cls().disable_all_events()
cls().enable_events_by_type(*cls.ENABLED_OPENEDX_EVENTS)
cls().allow_send_events_failure(*cls.ENABLED_OPENEDX_EVENTS)


def load_all_signals():
"""
Ensure OpenEdxPublicSignal.all_events() cache is fully populated.

Loads all non-test signals.py modules.
"""
found = set()

root = import_module('openedx_events')
for m in pkgutil.walk_packages(root.__path__, root.__name__ + '.'):
module_name = m.name
if 'tests' in module_name.split('.') or '.test_' in module_name:
continue
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't actually care about coverage here, but it's weird that this line is allegedly not covered. There should be about 10 test modules that hit this line during the walk, and I see them locally if I put a print statement here!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because Python has optimized away that line: nedbat/coveragepy#198

if module_name.endswith('.signals'):
import_module(module_name)
found.add(module_name)

# Check that the auto-discovered list matches the known modules.
# This is just here to ensure that the auto-discovery is working
# properly and doesn't start to silently fail.
#
# If this assertion fails because a module has been added, renamed,
# or deleted, please update the hardcoded list.
assert found == {
'openedx_events.content_authoring.signals',
'openedx_events.learning.signals',
}