diff --git a/launchable/commands/helper.py b/launchable/commands/helper.py index 2946a6bd6..181d99ce6 100644 --- a/launchable/commands/helper.py +++ b/launchable/commands/helper.py @@ -1,3 +1,4 @@ +from time import time from typing import Optional, Sequence, Tuple import click @@ -137,6 +138,12 @@ def find_or_create_session( return read_session(saved_build_name) +def time_ns(): + # time.time_ns() method is new in Python version 3.7 + # As a workaround, we convert time.time() to nanoseconds. + return int(time() * 1e9) + + def _check_observation_mode_status(session: str, is_observation: bool, tracking_client: TrackingClient, app: Optional[Application] = None): if not is_observation: diff --git a/launchable/commands/record/tests.py b/launchable/commands/record/tests.py index 8f75648de..75df09d99 100644 --- a/launchable/commands/record/tests.py +++ b/launchable/commands/record/tests.py @@ -22,7 +22,7 @@ from ...utils.logger import Logger from ...utils.no_build import NO_BUILD_BUILD_NAME, NO_BUILD_TEST_SESSION_ID from ...utils.session import parse_session, read_build -from ..helper import find_or_create_session +from ..helper import find_or_create_session, time_ns from .case_event import CaseEvent, CaseEventType GROUP_NAME_RULE = re.compile("^[a-zA-Z0-9][a-zA-Z0-9_-]*$") @@ -535,7 +535,16 @@ def recorded_result() -> Tuple[int, int, int, float]: return test_count, success_count, fail_count, duration / 60 # sec to min try: + start = time_ns() tc = testcases(self.reports) + end = time_ns() + tracking_client.send_event( + event_name=Tracking.Event.PERFORMANCE, + metadata={ + "elapsedTime": end - start, + "measurementTarget": "testcases method(parsing report file)" + } + ) if report_paths: # diagnostics mode to just report test paths @@ -543,6 +552,7 @@ def recorded_result() -> Tuple[int, int, int, float]: print(unparse_test_path(t['testPath'])) return + start = time_ns() exceptions = [] for chunk in ichunked(tc, post_chunk): p, es = payload( @@ -555,6 +565,14 @@ def recorded_result() -> Tuple[int, int, int, float]: send(p) exceptions.extend(es) + end = time_ns() + tracking_client.send_event( + event_name=Tracking.Event.PERFORMANCE, + metadata={ + "elapsedTime": end - start, + "measurementTarget": "events API" + } + ) if len(exceptions) > 0: raise Exception(exceptions) diff --git a/launchable/utils/tracking.py b/launchable/utils/tracking.py index 012316570..cc22c5258 100644 --- a/launchable/utils/tracking.py +++ b/launchable/utils/tracking.py @@ -13,6 +13,7 @@ class Tracking: # General events class Event(Enum): SHALLOW_CLONE = 'SHALLOW_CLONE' # this event is an example + PERFORMANCE = 'PERFORMANCE' # Error events class ErrorEvent(Enum): diff --git a/tests/commands/test_api_error.py b/tests/commands/test_api_error.py index 163329061..1fd8a55ad 100644 --- a/tests/commands/test_api_error.py +++ b/tests/commands/test_api_error.py @@ -451,7 +451,7 @@ def test_all_workflow_when_server_down(self): result = self.cli("record", "tests", "--session", self.session, "minitest", str(self.test_files_dir) + "/") self.assert_success(result) # Since Timeout error is caught inside of LaunchableClient, the tracking event is sent twice. - self.assert_tracking_count(tracking=tracking, count=8) + self.assert_tracking_count(tracking=tracking, count=9) def assert_tracking_count(self, tracking, count: int): # Prior to 3.6, `Response` object can't be obtained.