Skip to content
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
53 changes: 52 additions & 1 deletion samcli/lib/telemetry/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class EventType:

@staticmethod
def get_accepted_values(event_name: EventName) -> List[str]:
"""Get all acceptable values for a given Event."""
"""Get all acceptable values for a given Event name."""
if event_name not in EventType._events:
return []
return EventType._events[event_name]
Expand All @@ -54,6 +54,12 @@ def __init__(self, event_name: str, event_value: str):
def __eq__(self, other):
return self.event_name == other.event_name and self.event_value == other.event_value

def __repr__(self):
return f"Event(event_name={self.event_name.value}, event_value={self.event_value})"

def to_json(self):
return {"event_name": self.event_name.value, "event_value": self.event_value}

@staticmethod
def _verify_event(event_name: str, event_value: str) -> None:
"""Raise an EventCreationError if either the event name or value is not valid."""
Expand All @@ -68,5 +74,50 @@ def _get_event_names() -> List[str]:
return [event.value for event in EventName]


class EventTracker:
"""Class to track and recreate Events as they occur."""

_events: List[Event] = []

@staticmethod
def track_event(event_name: str, event_value: str):
"""Method to track an event where and when it occurs.

Place this method in the codepath of the event that you would
like to track. For instance, if you would like to track when
FeatureX is used, append this method to the end of that function.

Parameters
----------
event_name: str
The name of the Event. Must be a valid EventName value, or an
EventCreationError will be thrown.
event_value: str
The value of the Event. Must be a valid EventType value for the
passed event_name, or an EventCreationError will be thrown.

Examples
--------
>>> def feature_x(...):
# do things
EventTracker.track_event("UsedFeature", "FeatureX")

>>> def feature_y(...) -> Any:
# do things
EventTracker.track_event("UsedFeature", "FeatureY")
return some_value
"""
EventTracker._events.append(Event(event_name, event_value))

@staticmethod
def get_tracked_events() -> List[Event]:
return EventTracker._events

@staticmethod
def clear_trackers():
"""Clear the current list of tracked Events before the next session."""
EventTracker._events = []


class EventCreationError(Exception):
"""Exception called when an Event is not properly created."""
32 changes: 31 additions & 1 deletion tests/unit/lib/telemetry/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from unittest import TestCase
from unittest.mock import Mock, patch

from samcli.lib.telemetry.event import Event, EventCreationError
from samcli.lib.telemetry.event import Event, EventCreationError, EventTracker


class DummyEventName(Enum):
Expand Down Expand Up @@ -48,3 +48,33 @@ def test_create_event_name_doesnt_exist(self):
Event("SomeEventThatDoesn'tExist", "value1")

self.assertEqual(e.exception.args[0], "Event 'SomeEventThatDoesn'tExist' does not exist.")

@patch("samcli.lib.telemetry.event.Event._verify_event")
@patch("samcli.lib.telemetry.event.EventType")
@patch("samcli.lib.telemetry.event.EventName")
def test_event_to_json(self, name_mock, type_mock, verify_mock):
name_mock.return_value = Mock(value="Testing")
type_mock.get_accepted_values.return_value = ["value1"]
verify_mock.return_value = None

test_event = Event("Testing", "value1")

self.assertEqual(test_event.to_json(), {"event_name": "Testing", "event_value": "value1"})


class TestEventTracker(TestCase):
@patch("samcli.lib.telemetry.event.Event")
def test_track_event(self, event_mock):
# Test that an event can be tracked
dummy_event = Mock(event_name="Test", event_value="SomeValue")
event_mock.return_value = dummy_event

EventTracker.track_event("Test", "SomeValue")

self.assertEqual(len(EventTracker._events), 1)
self.assertEqual(EventTracker._events[0], dummy_event)

# Test that the Event list will be cleared
EventTracker.clear_trackers()

self.assertEqual(len(EventTracker._events), 0)