Skip to content

Commit

Permalink
chore(iast): restore, update and improve the native import smoke_test (
Browse files Browse the repository at this point in the history
…#11278)

## Description

The previous smoke test for importing ddtrace IAST native module (both
positive and negative routes) was removed on a previous PR.

This restores it, adapting it to the new version (now the `_native`
module doesn't produce an `ImportError` if `DD_IAST_ENABLED=0` but a
warning log message). It will also run both positive and negative tests
in a subprocess so the `.so` module doesn't have to be restarted or
reloaded, which is not trivial for native modules.

## Checklist
- [X] PR author has checked that all the criteria below are met
- The PR description includes an overview of the change
- The PR description articulates the motivation for the change
- The change includes tests OR the PR description describes a testing
strategy
- The PR description notes risks associated with the change, if any
- Newly-added code is easy to change
- The change follows the [library release note
guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html)
- The change includes or references documentation updates if necessary
- Backport labels are set (if
[applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting))

## Reviewer Checklist
- [x] Reviewer has checked that all the criteria below are met 
- Title is accurate
- All changes are related to the pull request's stated goal
- Avoids breaking
[API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces)
changes
- Testing strategy adequately addresses listed risks
- Newly-added code is easy to change
- Release note makes sense to a user of the library
- If necessary, author has acknowledged and discussed the performance
implications of this PR as reported in the benchmarks PR comment
- Backport labels are set in a manner that is consistent with the
[release branch maintenance
policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)

---------

Signed-off-by: Juanjo Alvarez <[email protected]>
  • Loading branch information
juanjux authored Nov 5, 2024
1 parent 79c0cf6 commit 19f4c58
Showing 1 changed file with 73 additions and 11 deletions.
84 changes: 73 additions & 11 deletions tests/smoke_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import copy
import os
from platform import system
import subprocess
import sys

import ddtrace.appsec._ddwaf
import ddtrace.bootstrap.sitecustomize as module
import textwrap


def mac_supported_iast_version():
Expand All @@ -14,13 +15,74 @@ def mac_supported_iast_version():
return True


# Code need to be run in a separate subprocess to reload since reloading .so files doesn't
# work like normal Python ones
test_native_load_code = """
import os
import sys
import logging
log_messages = []
class ListHandler(logging.Handler):
def emit(self, record):
log_messages.append(record.getMessage())
# the _native module will produce the "IAST not enabled..." message using the root logger (logger.warning)
# so we have to configure the capture handler on the root logger
root_logger = logging.getLogger()
root_logger.addHandler(ListHandler())
root_logger.setLevel(logging.WARNING)
try:
from ddtrace.appsec._iast._taint_tracking._native import ops
if os.environ.get("DD_IAST_ENABLED") == "False":
assert any(
"IAST not enabled but native module is being loaded" in message
for message in log_messages
)
else:
assert ops
assert len(log_messages) == 0
except ImportError as e:
assert False, "Importing the native module failed, _native probably not compiled correctly: %s" % str(e)
"""

if __name__ == "__main__":
# ASM IAST smoke test
if sys.version_info >= (3, 6, 0) and system() != "Windows" and mac_supported_iast_version():
print("Running native IAST module load test...")
test_code = textwrap.dedent(test_native_load_code)
cmd = [sys.executable, "-c", test_code]
orig_env = os.environ.copy()
copied_env = copy.deepcopy(orig_env)

try:
print("Running native module load test with DD_IAST_ENABLED=False...")
copied_env["DD_IAST_ENABLED"] = "False"
result = subprocess.run(cmd, env=copied_env, capture_output=True, text=True)
assert result.returncode == 0, "Failed with DD_IAST_ENABLED=0: %s, %s" % (result.stdout, result.stderr)

print("Running native module load test with DD_IAST_ENABLED=True...")
copied_env["DD_IAST_ENABLED"] = "True"
result = subprocess.run(cmd, env=copied_env, capture_output=True, text=True)
assert result.returncode == 0, "Failed with DD_IAST_ENABLED=1: %s, %s" % (result.stdout, result.stderr)
print("IAST module load tests completed successfully")
finally:
os.environ = orig_env

# ASM WAF smoke test
if system() == "Linux":
if not sys.maxsize > 2**32:
# 32-bit linux DDWAF not ready yet.
sys.exit(0)

ddtrace.appsec._ddwaf.version()
assert ddtrace.appsec._ddwaf._DDWAF_LOADED
assert module.loaded
if system() != "Linux" or sys.maxsize > 2**32:
import ddtrace.appsec._ddwaf
import ddtrace.bootstrap.sitecustomize as module

print("Running WAF module load test...")
# Proceed with the WAF module load test
ddtrace.appsec._ddwaf.version()
assert ddtrace.appsec._ddwaf._DDWAF_LOADED
assert module.loaded
print("WAF module load test completed successfully")
else:
# Skip the test for 32-bit Linux systems
print("Skipping test, 32-bit DDWAF not ready yet")

0 comments on commit 19f4c58

Please sign in to comment.