def test_stress(self): """ Stress tests to schedule a lot of threads which works super fast (do nothing) with sending messages." """ tm = TelemetrySender() fake_backend = FakeTelemetryBackend() for _ in range(1000000): tm.send(fake_backend, None)
def __init__(self, app_name: str = None, app_version: str = None, tid: [None, str] = None, backend: [str, None] = 'ga'): if not hasattr(self, 'tid'): self.tid = None if app_name is not None: self.consent = isip.isip_consent() == isip.ISIPConsent.APPROVED # override default tid if tid is not None: self.tid = tid self.backend = BackendRegistry.get_backend(backend)(self.tid, app_name, app_version) self.sender = TelemetrySender() else: # use already configured instance assert self.sender is not None, 'The first instantiation of the Telemetry should be done with the ' \ 'application name and version'
def test_check_shutdown_negative(self): """ Test to check that without forcing shutdown total execution time is expected. """ tm = TelemetrySender(1) # only one worker thread fake_backend = FakeTelemetryBackendWithSleep() start_time = time.time() # schedule 5 requests which totally should work more than 4 seconds for _ in range(5): tm.send(fake_backend, None) try: # wait until all threads finish their work. We use internal ThreadPoolExecutor attribute _work_queue to make # sure that all workers completed their work, so the whole code is wrapped to try/except to avoid exceptions # if internal implementation is changed in the future while tm.executor._work_queue.qsize(): pass self.assertTrue(time.time() - start_time > 4.0) except: pass
def test_check_shutdown(self): """ Stress test to schedule many threads taking 1 second and then ask to force shutdown. Make sure that the elapsed time is small. """ tm = TelemetrySender() fake_backend = FakeTelemetryBackendWithSleep() # schedule many requests which just wait 1 second for _ in range(100000): tm.send(fake_backend, None) start_time = time.time() # ask to shutdown with timeout of 1 second tm.force_shutdown(1) while len(tm.executor._threads): pass # check that no more than 3 seconds spent self.assertTrue(time.time() - start_time < 3)
class Telemetry(metaclass=SingletonMetaClass): """ The main class to send telemetry data. It uses singleton pattern. The instance should be initialized with the application name, version and tracking id just once. Later the instance can be created without parameters. """ def __init__(self, app_name: str = None, app_version: str = None, tid: [None, str] = None, backend: [str, None] = 'ga'): if not hasattr(self, 'tid'): self.tid = None if app_name is not None: self.consent = isip.isip_consent() == isip.ISIPConsent.APPROVED # override default tid if tid is not None: self.tid = tid self.backend = BackendRegistry.get_backend(backend)(self.tid, app_name, app_version) self.sender = TelemetrySender() else: # use already configured instance assert self.sender is not None, 'The first instantiation of the Telemetry should be done with the ' \ 'application name and version' def force_shutdown(self, timeout: float = 1.0): """ Stops currently running threads which may be hanging because of no Internet connection. :param timeout: maximum timeout time :return: None """ self.sender.force_shutdown(timeout) def send_event(self, event_category: str, event_action: str, event_label: str, event_value: int = 1, **kwargs): """ Send single event. :param event_category: category of the event :param event_action: action of the event :param event_label: the label associated with the action :param event_value: the integer value corresponding to this label :param kwargs: additional parameters :return: None """ if self.consent: self.sender.send( self.backend, self.backend.build_event_message(event_category, event_action, event_label, event_value, **kwargs)) def start_session(self, **kwargs): """ Sends a message about starting of a new session. :param kwargs: additional parameters :return: None """ if self.consent: self.sender.send( self.backend, self.backend.build_session_start_message(**kwargs)) def end_session(self, **kwargs): """ Sends a message about ending of the current session. :param kwargs: additional parameters :return: None """ if self.consent: self.sender.send(self.backend, self.backend.build_session_end_message(**kwargs)) def send_error(self, error_msg: str, **kwargs): if self.consent: pass def send_stack_trace(self, stack_trace: str, **kwargs): if self.consent: pass