-
Notifications
You must be signed in to change notification settings - Fork 46
Improve testing for ddtrace imports. #662
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
Conversation
e330818
to
a4b9c9d
Compare
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
@patch("datadog_lambda.config.Config.exception_replay_enabled", True) | ||
def test_exception_replay_enabled(monkeypatch): | ||
importlib.reload(wrapper) | ||
|
||
original_SpanExceptionHandler_enable = wrapper.SpanExceptionHandler.enable | ||
SpanExceptionHandler_enable_calls = [] | ||
|
||
def SpanExceptionHandler_enable(*args, **kwargs): | ||
SpanExceptionHandler_enable_calls.append((args, kwargs)) | ||
return original_SpanExceptionHandler_enable(*args, **kwargs) | ||
|
||
original_SignalUploader_periodic = wrapper.SignalUploader.periodic | ||
SignalUploader_periodic_calls = [] | ||
|
||
def SignalUploader_periodic(*args, **kwargs): | ||
SignalUploader_periodic_calls.append((args, kwargs)) | ||
return original_SignalUploader_periodic(*args, **kwargs) | ||
|
||
monkeypatch.setattr( | ||
"datadog_lambda.wrapper.SpanExceptionHandler.enable", | ||
SpanExceptionHandler_enable, | ||
) | ||
monkeypatch.setattr( | ||
"datadog_lambda.wrapper.SignalUploader.periodic", SignalUploader_periodic | ||
) | ||
|
||
expected_response = { | ||
"statusCode": 200, | ||
"body": "This should be returned", | ||
} | ||
|
||
@wrapper.datadog_lambda_wrapper | ||
def lambda_handler(event, context): | ||
return expected_response | ||
|
||
response = lambda_handler({}, get_mock_context()) | ||
|
||
assert response == expected_response | ||
assert len(SpanExceptionHandler_enable_calls) == 1 | ||
assert len(SignalUploader_periodic_calls) == 1 | ||
|
||
|
||
@patch("datadog_lambda.config.Config.profiling_enabled", True) | ||
def test_profiling_enabled(monkeypatch): | ||
importlib.reload(wrapper) | ||
|
||
original_Profiler_start = wrapper.profiler.Profiler.start | ||
Profiler_start_calls = [] | ||
|
||
def Profiler_start(*args, **kwargs): | ||
Profiler_start_calls.append((args, kwargs)) | ||
return original_Profiler_start(*args, **kwargs) | ||
|
||
monkeypatch.setattr("datadog_lambda.wrapper.is_new_sandbox", lambda: True) | ||
monkeypatch.setattr( | ||
"datadog_lambda.wrapper.profiler.Profiler.start", Profiler_start | ||
) | ||
|
||
expected_response = { | ||
"statusCode": 200, | ||
"body": "This should be returned", | ||
} | ||
|
||
@wrapper.datadog_lambda_wrapper | ||
def lambda_handler(event, context): | ||
return expected_response | ||
|
||
response = lambda_handler({}, get_mock_context()) | ||
|
||
assert response == expected_response | ||
assert len(Profiler_start_calls) == 1 | ||
|
||
|
||
@patch("datadog_lambda.config.Config.llmobs_enabled", True) | ||
def test_llmobs_enabled(monkeypatch): | ||
importlib.reload(wrapper) | ||
|
||
original_LLMObs_enable = wrapper.LLMObs.enable | ||
LLMObs_enable_calls = [] | ||
|
||
def LLMObs_enable(*args, **kwargs): | ||
LLMObs_enable_calls.append((args, kwargs)) | ||
return original_LLMObs_enable(*args, **kwargs) | ||
|
||
original_LLMObs_flush = wrapper.LLMObs.flush | ||
LLMObs_flush_calls = [] | ||
|
||
def LLMObs_flush(*args, **kwargs): | ||
LLMObs_flush_calls.append((args, kwargs)) | ||
return original_LLMObs_flush(*args, **kwargs) | ||
|
||
monkeypatch.setattr("datadog_lambda.wrapper.LLMObs.enable", LLMObs_enable) | ||
monkeypatch.setattr("datadog_lambda.wrapper.LLMObs.flush", LLMObs_flush) | ||
|
||
expected_response = { | ||
"statusCode": 200, | ||
"body": "This should be returned", | ||
} | ||
|
||
@wrapper.datadog_lambda_wrapper | ||
def lambda_handler(event, context): | ||
return expected_response | ||
|
||
response = lambda_handler({}, get_mock_context()) | ||
|
||
assert response == expected_response | ||
assert len(LLMObs_enable_calls) == 1 | ||
assert len(LLMObs_flush_calls) == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid starting real ddtrace instrumentation in unit tests
The new tests monkeypatch the ddtrace hooks but still call the original implementations (SpanExceptionHandler.enable
, SignalUploader.periodic
, profiler.Profiler.start
, LLMObs.enable
/flush
). Executing those real implementations requires optional ddtrace extras and spins up background workers; in environments where profiling or exception-replay components are not installed or configured, the imports and start()
/enable()
calls will raise or leave threads running, causing CI failures and flaky behavior. To verify that the wrapper invokes these hooks, stub them and record the calls rather than invoking the underlying implementations.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ltgm
…python still valid (#14746) ## Description <!-- Provide an overview of the change and motivation for the change --> Customer reported that a class name changed in the most recent version of ddtrace which was then causing errors when attempting to import `datadog_lambda`. See DataDog/datadog-lambda-python#661 and #14653. ## Testing <!-- Describe your testing strategy or note what tests are included --> ## Risks <!-- Note any risks associated with this change, or "None" if no risks --> It's just some tests, so risk is low. ## Additional Notes <!-- Any other information that would be helpful for reviewers --> Added additional tests on the `datadog_lambda` side as well, including running our unit tests twice a day. See DataDog/datadog-lambda-python#662.
What does this PR do?
datadog_lambda.wrapper
Motivation
#661
Testing Guidelines
Additional Notes
We should ideally also have similar tests in dd-trace-py to ensure that these methods are not renamed in the first place.
Types of Changes
Check all that apply