Skip to content

Commit

Permalink
SNOW-1516350: disable oob telemetry (#1991)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-aling authored Jul 12, 2024
1 parent 3e66c08 commit 0d00519
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 175 deletions.
6 changes: 3 additions & 3 deletions src/snowflake/connector/telemetry_oob.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def __init__(self) -> None:
raise Exception("This class is a singleton!")
else:
TelemetryService.__instance = self
self._enabled = True
self._enabled = False
self._queue = Queue()
self.batch_size = DEFAULT_BATCH_SIZE
self.num_of_retry_to_trigger_telemetry = (
Expand All @@ -192,11 +192,11 @@ def __del__(self) -> None:
@property
def enabled(self) -> bool:
"""Whether the Telemetry service is enabled or not."""
return self._enabled
return False

def enable(self) -> None:
"""Enable Telemetry Service."""
self._enabled = True
self._enabled = False

def disable(self) -> None:
"""Disable Telemetry Service."""
Expand Down
182 changes: 10 additions & 172 deletions test/unit/test_telemetry_oob.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,12 @@

from __future__ import annotations

import logging
import time
from concurrent.futures import ThreadPoolExecutor

import pytest

import snowflake.connector.errorcode
import snowflake.connector.telemetry
from snowflake.connector.description import CLIENT_NAME, SNOWFLAKE_CONNECTOR_VERSION
from snowflake.connector.errorcode import ER_FAILED_TO_REQUEST
from snowflake.connector.errors import RevocationCheckError
from snowflake.connector.ocsp_snowflake import OCSPTelemetryData
from snowflake.connector.sqlstate import SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED
from snowflake.connector.telemetry_oob import TelemetryService

DEV_CONFIG = {
"host": "localhost",
"port": 8080,
"account": "testAccount",
"user": "test",
"password": "ShouldNotShowUp",
"protocol": "http",
}
TEST_RACE_CONDITION_THREAD_COUNT = 2
TEST_RACE_CONDITION_DELAY_SECONDS = 1
telemetry_data = {}
Expand All @@ -46,167 +29,22 @@
method = "POST"


@pytest.fixture()
def telemetry_setup(request):
"""Sets up the telemetry service by enabling it and flushing any entries."""
def test_telemetry_oob_disabled():
telemetry = TelemetryService.get_instance()
telemetry.update_context(DEV_CONFIG)
assert not telemetry.enabled
telemetry.enable()
telemetry.flush()


def test_telemetry_oob_simple_flush(telemetry_setup, caplog):
"""Tests capturing and sending a simple OCSP Exception message."""
telemetry = TelemetryService.get_instance()
telemetry.flush() # clear the buffer first
telemetry.log_ocsp_exception(
event_type, telemetry_data, exception=exception, stack_trace=stack_trace
)
assert telemetry.size() == 1
caplog.set_level(logging.DEBUG, "snowflake.connector.telemetry_oob")
telemetry.flush()
assert (
"Failed to generate a JSON dump from the passed in telemetry OOB events"
not in caplog.text
)
# since pytests can run test in parallel and TelemetryService is a singleton, other tests
# might encounter error logged into the queue of the OOB Telemetry simultaneously
# leading to assert telemetry.size() == 0 failure
# here we check that the OCSP exception event in the test is flushed
for event in list(telemetry.queue.queue):
assert "OCSPException" not in event.name


@pytest.mark.flaky(reruns=3)
def test_telemetry_oob_urgent(telemetry_setup):
"""Tests sending an urgent OCSP Exception message."""
telemetry = TelemetryService.get_instance()

telemetry.log_ocsp_exception(
event_type,
telemetry_data,
exception=exception,
stack_trace=stack_trace,
urgent=True,
)
assert telemetry.size() == 0


def test_telemetry_oob_close(telemetry_setup):
"""Tests closing the Telemetry Service when there are still messages in the queue."""
telemetry = TelemetryService.get_instance()

telemetry.log_ocsp_exception(
event_type, telemetry_data, exception=exception, stack_trace=stack_trace
)
assert telemetry.size() == 1
telemetry.close()
assert telemetry.size() == 0


def test_telemetry_oob_close_empty(telemetry_setup):
"""Tests closing the Telemetry Service when the queue is empty."""
telemetry = TelemetryService.get_instance()

assert telemetry.size() == 0
telemetry.close()
assert telemetry.size() == 0


def test_telemetry_oob_log_when_disabled(telemetry_setup):
"""Tests trying to log to the telemetry service when it is disabled."""
telemetry = TelemetryService.get_instance()

assert telemetry.size() == 0
assert not telemetry.enabled
telemetry.disable()
assert not telemetry.enabled
telemetry.enable()
telemetry.log_ocsp_exception(
event_type, telemetry_data, exception=exception, stack_trace=stack_trace
)
assert telemetry.size() == 0
telemetry.enable()


def test_telemetry_oob_http_log(telemetry_setup):
"""Tests sending a simple HTTP request telemetry event."""
telemetry = TelemetryService.get_instance()

telemetry.log_http_request_error(
event_name,
url,
method,
SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED,
ER_FAILED_TO_REQUEST,
exception=exception,
stack_trace=stack_trace,
)
assert telemetry.size() == 1
telemetry.flush()
assert telemetry.size() == 0


def test_telemetry_oob_error_code_mapping():
"""Tests that all OCSP error codes have a corresponding Telemetry sub event type."""
ec_dict = snowflake.connector.errorcode.__dict__
for ec, ec_val in ec_dict.items():
if not ec.startswith("__") and ec not in ("annotations",):
if 254000 <= ec_val < 255000:
assert ec_val in OCSPTelemetryData.ERROR_CODE_MAP


@pytest.mark.flaky(reruns=3)
def test_telemetry_oob_http_log_urgent(telemetry_setup):
"""Tests sending an urgent HTTP request telemetry event."""
telemetry = TelemetryService.get_instance()

assert telemetry.size() == 0
telemetry.log_http_request_error(
event_name,
url,
method,
SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED,
ER_FAILED_TO_REQUEST,
exception=exception,
stack_trace=stack_trace,
urgent=True,
)
assert telemetry.size() == 0


def test_generate_telemetry_with_driver_info():
assert snowflake.connector.telemetry.generate_telemetry_data_dict(
is_oob_telemetry=True
) == {
snowflake.connector.telemetry.TelemetryField.KEY_OOB_DRIVER.value: CLIENT_NAME,
snowflake.connector.telemetry.TelemetryField.KEY_OOB_VERSION.value: SNOWFLAKE_CONNECTOR_VERSION,
}

assert snowflake.connector.telemetry.generate_telemetry_data_dict(
from_dict={}, is_oob_telemetry=True
) == {
snowflake.connector.telemetry.TelemetryField.KEY_OOB_DRIVER.value: CLIENT_NAME,
snowflake.connector.telemetry.TelemetryField.KEY_OOB_VERSION.value: SNOWFLAKE_CONNECTOR_VERSION,
}

assert snowflake.connector.telemetry.generate_telemetry_data_dict(
from_dict={"key": "value"}, is_oob_telemetry=True
) == {
snowflake.connector.telemetry.TelemetryField.KEY_OOB_DRIVER.value: CLIENT_NAME,
snowflake.connector.telemetry.TelemetryField.KEY_OOB_VERSION.value: SNOWFLAKE_CONNECTOR_VERSION,
"key": "value",
}

assert snowflake.connector.telemetry.generate_telemetry_data_dict(
from_dict={
snowflake.connector.telemetry.TelemetryField.KEY_OOB_DRIVER.value: "CUSTOM_CLIENT_NAME",
snowflake.connector.telemetry.TelemetryField.KEY_OOB_VERSION.value: "1.2.3",
"key": "value",
},
is_oob_telemetry=True,
) == {
snowflake.connector.telemetry.TelemetryField.KEY_OOB_DRIVER.value: "CUSTOM_CLIENT_NAME",
snowflake.connector.telemetry.TelemetryField.KEY_OOB_VERSION.value: "1.2.3",
"key": "value",
}
assert telemetry.queue.empty()
telemetry.log_general_exception(event_name, {})
assert telemetry.queue.empty()
telemetry.log_http_request_error(event_name, url, method, "error", "error")
assert telemetry.queue.empty()


class MockTelemetryService(TelemetryService):
Expand Down

0 comments on commit 0d00519

Please sign in to comment.